﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Linq;

namespace Lightray.Hattrick.ChppLib
{
    [Serializable()]
    public struct ITrickStorageEntry : ISerializable
    {
        public DateTime WrittenDate { get; set; }
        public FetchRequest OriginalRequest { get; set; }
        public TimeSpan OffsetFromHattrickTime { get; set; }
        public int MyTeamId { get; set; }
        public int MyUserId { get; set; }

        public XDocument MyTeam { get; set; }
        public XDocument MyPlayers { get; set; }
        public XDocument MyYouthPlayers { get; set; }
        public XDocument MyMatches { get; set; }
        public XDocument MyLeague { get; set; }
        public XDocument MyRegion { get; set; }
        public XDocument MyEconomy { get; set; }
        public XDocument MyCountry { get; set; }
        public XDocument MyLastMatchDeatils { get; set; }
        public IEnumerable<XDocument> MyLeagueOtherTeams { get; set; }

        #region ISerializable Members

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("WrittenDate", WrittenDate);
            info.AddValue("OriginalRequest", OriginalRequest);
            info.AddValue("OffsetFromHattrickTime", OffsetFromHattrickTime);
            info.AddValue("MyTeamId", MyTeamId);
            info.AddValue("MyUserId", MyUserId);
            addXml(info, "MyTeam", MyTeam);
            addXml(info, "MyPlayers", MyPlayers);
            addXml(info, "MyYouthPlayers", MyYouthPlayers);
            addXml(info, "MyMatches", MyMatches);
            addXml(info, "MyLeague", MyLeague);
            addXml(info, "MyRegion", MyRegion);
            addXml(info, "MyEconomy", MyEconomy);
            addXml(info, "MyCountry", MyCountry);
            addXml(info, "MyLastMatchDeatils", MyLastMatchDeatils);
            addXmlCollection(info, "MyLeagueOtherTeams", MyLeagueOtherTeams);          
        }

        public ITrickStorageEntry(SerializationInfo info, StreamingContext context)
            : this()
        {
            foreach (SerializationEntry e in info)
            {
                switch (e.Name)
                {
                    case "WrittenDate":
                        WrittenDate = (DateTime)e.Value;
                        break;

                    case "OriginalRequest":
                        OriginalRequest = (FetchRequest)e.Value;
                        break;

                    case "OffsetFromHattrickTime":
                        OffsetFromHattrickTime = (TimeSpan)e.Value;
                        break;

                    case "MyTeamId":
                        MyTeamId = (int)e.Value;
                        break;

                    case "MyUserId":
                        MyUserId = (int)e.Value;
                        break;

                    case "MyTeam":
                        MyTeam = getXml(e);
                        break;

                    case "MyPlayers":
                        MyPlayers = getXml(e);
                        break;

                    case "MyYouthPlayers":
                        MyYouthPlayers = getXml(e);
                        break;
                    case "MyMatches":
                        MyMatches = getXml(e);
                        break;

                    case "MyLeague":
                        MyLeague = getXml(e);
                        break;

                    case "MyRegion":
                        MyRegion = getXml(e);
                        break;

                    case "MyEconomy":
                        MyEconomy = getXml(e);
                        break;

                    case "MyCountry":
                        MyCountry = getXml(e);
                        break;

                    case "MyLastMatchDeatils":
                        MyLastMatchDeatils = getXml(e);
                        break;

                    case "MyLeagueOtherTeams":
                        MyLeagueOtherTeams = getXmlCollection(e);
                        break;
                }                
            }                               
        }

        private void addXmlCollection(SerializationInfo info, string name, IEnumerable<XDocument> xmlCollection)
        {
            if (xmlCollection == null)
            {
                info.AddValue(name, null);
                return;
            }

            List<string> xmlStrings = new List<string>();
            foreach (var xml in xmlCollection)
                xmlStrings.Add(xml.ToString());
            info.AddValue(name, xmlStrings);
        }

        private void addXml(SerializationInfo info, string name, XDocument xml)
        {
            info.AddValue(name, xml != null ? xml.ToString() : string.Empty);
        }
     
        private XDocument getXml(SerializationEntry e)
        {
            try
            {
                string xmlString = e.Value as string;
                if (string.IsNullOrEmpty(xmlString))
                    return null;

                return XDocument.Parse(xmlString);
            }
            catch (Exception)
            {
                return null; // no xml, or maybe serialized member does not exist (reading old file structure?)
            }
        }

        IEnumerable<XDocument> getXmlCollection(SerializationEntry e)
        {
            List<string> xmlStrings = e.Value as List<string>;
            if (xmlStrings == null)
                return null;

            List<XDocument> xmlCollection = new List<XDocument>();
            foreach (var xmlString in xmlStrings)
            {
                try
                {
                    xmlCollection.Add(XDocument.Parse(xmlString));
                }
                catch (XmlException) { }
            }
            return xmlCollection;
        }

        #endregion
    }
}
